package com.slj.authorization_resource_server.config;

import jakarta.annotation.Resource;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtValidators;
import org.springframework.security.oauth2.jwt.MappedJwtClaimSetConverter;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;

import java.time.Duration;
import java.util.Collections;

@Configuration
@EnableWebSecurity
public class ResourceServerConfig {

    @Resource
    private RestTemplateBuilder restTemplateBuilder;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/resource/**").hasAuthority("SCOPE_message:read")
                        .requestMatchers("/users/**").hasAnyAuthority("SCOPE_message:write")
                        .anyRequest().authenticated()
                )
                .oauth2ResourceServer(oauth2 -> oauth2
                        .jwt(jwt -> jwt.decoder(jwtDecoder(restTemplateBuilder))
                        )
                );
        return http.build();
    }


    @Bean
    public JwtDecoder jwtDecoder(RestTemplateBuilder builder) {
        // 授权服务器 jwk 的信息
        NimbusJwtDecoder decoder = NimbusJwtDecoder.withJwkSetUri("http://127.0.0.1:8080/oauth2/jwks")
                // 设置获取 jwk 信息的超时时间
                .restOperations(
                        builder.setReadTimeout(Duration.ofSeconds(3))
                                .setConnectTimeout(Duration.ofSeconds(3))
                                .build()
                )
                .build();
        // 对jwt进行校验
        decoder.setJwtValidator(JwtValidators.createDefault());
        // 对 jwt 的 claim 中增加值
        decoder.setClaimSetConverter(
                MappedJwtClaimSetConverter.withDefaults(Collections.singletonMap("为claim中增加key", custom -> "值"))
        );
        return decoder;
    }

}
